home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 2 / Atari Mega Archive CD - Volume 2.iso / minix / up1510b.tgz / up1510b / src / lib / other / printk.c < prev    next >
C/C++ Source or Header  |  1990-07-23  |  4KB  |  258 lines

  1. #include <lib.h>
  2. #include <stdarg.h>
  3.  
  4. /* three compile time options:
  5.  *    NO_LONGD    %d and %ld/%D are equal
  6.  *    NO_FLOAT    abort on %e, %f and %g
  7.  */
  8.  
  9. #define    NO_FLOAT
  10.  
  11. #ifdef NO_FLOAT
  12. #define    MAXDIG        11    /* 32 bits in radix 8 */
  13. #else
  14. #define    MAXDIG        128    /* this must be enough */
  15. #endif
  16.  
  17. _PROTOTYPE( void putc, (int ch));    /* user-supplied, should be putk */
  18.  
  19. PRIVATE _PROTOTYPE( char *_itoa, (char *p, unsigned num, int radix));
  20. #ifndef NO_LONGD
  21. PRIVATE _PROTOTYPE( char *ltoa, (char *p, unsigned long num, int radix));
  22. #endif
  23.  
  24. PRIVATE char *_itoa(p, num, radix)
  25. register char *p;
  26. register unsigned num;
  27. register radix;
  28. {
  29.   register i;
  30.   register char *q;
  31.  
  32.   q = p + MAXDIG;
  33.   do {
  34.         i = (int) (num % radix);
  35.         i += '0';
  36.         if (i > '9') i += 'A' - '0' - 10;
  37.         *--q = i;
  38.   } while (num = num / radix);
  39.   i = p + MAXDIG - q;
  40.   do
  41.         *p++ = *q++;
  42.   while (--i);
  43.   return(p);
  44. }
  45.  
  46. #ifndef NO_LONGD
  47. PRIVATE char *ltoa(p, num, radix)
  48. register char *p;
  49. register unsigned long num;
  50. register radix;
  51. {
  52.   register i;
  53.   register char *q;
  54.  
  55.   q = p + MAXDIG;
  56.   do {
  57.     i = (int) (num % radix);
  58.     i += '0';
  59.     if (i > '9') i += 'A' - '0' - 10;
  60.     *--q = i;
  61.   } while (num = num / radix);
  62.   i = p + MAXDIG - q;
  63.   do
  64.     *p++ = *q++;
  65.   while (--i);
  66.   return(p);
  67. }
  68.  
  69. #endif
  70.  
  71. #ifndef NO_FLOAT
  72. extern char *_ecvt();
  73. extern char *_fcvt();
  74. extern char *_gcvt();
  75. #endif
  76.  
  77. #define    GETARG(typ)    va_arg(args, typ)
  78.  
  79. void printk(fmt, arg1)
  80. register char *fmt;
  81. int arg1;
  82. {
  83.   char buf[MAXDIG + 1];        /* +1 for sign */
  84.   register int *args = &arg1;
  85.   register char *p;
  86.   register char *s;
  87.   register c;
  88.   register i;
  89.   register short width;
  90.   register short ndigit;
  91.   register ndfnd;
  92.   register ljust;
  93.   register zfill;
  94. #ifndef NO_LONGD
  95.   register lflag;
  96.   register long l;
  97. #endif
  98.  
  99.   for (;;) {
  100.     c = *fmt++;
  101.     if (c == 0) return;
  102.     if (c != '%') {
  103.         putc(c);
  104.         continue;
  105.     }
  106.     p = buf;
  107.     s = buf;
  108.     ljust = 0;
  109.     if (*fmt == '-') {
  110.         fmt++;
  111.         ljust++;
  112.     }
  113.     zfill = ' ';
  114.     if (*fmt == '0') {
  115.         fmt++;
  116.         zfill = '0';
  117.     }
  118.     for (width = 0;;) {
  119.         c = *fmt++;
  120.         if (c >= '0' && c <= '9')
  121.             c -= '0';
  122.         else if (c == '*')
  123.             c = GETARG(int);
  124.         else
  125.             break;
  126.         width *= 10;
  127.         width += c;
  128.     }
  129.     ndfnd = 0;
  130.     ndigit = 0;
  131.     if (c == '.') {
  132.         for (;;) {
  133.             c = *fmt++;
  134.             if (c >= '0' && c <= '9')
  135.                 c -= '0';
  136.             else if (c == '*')
  137.                 c = GETARG(int);
  138.             else
  139.                 break;
  140.             ndigit *= 10;
  141.             ndigit += c;
  142.             ndfnd++;
  143.         }
  144.     }
  145. #ifndef NO_LONGD
  146.     lflag = 0;
  147. #endif
  148.     if (c == 'l' || c == 'L') {
  149. #ifndef NO_LONGD
  150.         lflag++;
  151. #endif
  152.         if (*fmt) c = *fmt++;
  153.     }
  154.     switch (c) {
  155.         case 'X':
  156. #ifndef NO_LONGD
  157.         lflag++;
  158. #endif
  159.         case 'x':
  160.         c = 16;
  161.         goto oxu;
  162.         case 'U':
  163. #ifndef NO_LONGD
  164.         lflag++;
  165. #endif
  166.         case 'u':
  167.         c = 10;
  168.         goto oxu;
  169.         case 'O':
  170. #ifndef NO_LONGD
  171.         lflag++;
  172. #endif
  173.         case 'o':
  174.         c = 8;
  175.   oxu:
  176. #ifndef NO_LONGD
  177.         if (lflag) {
  178.             p = ltoa(p, (unsigned long)GETARG(long), c);
  179.             break;
  180.         }
  181. #endif
  182.         p = _itoa(p, (unsigned int)GETARG(int), c);
  183.         break;
  184.         case 'D':
  185. #ifndef NO_LONGD
  186.         lflag++;
  187. #endif
  188.         case 'd':
  189. #ifndef NO_LONGD
  190.         if (lflag) {
  191.             if ((l = GETARG(long)) < 0) {
  192.                 *p++ = '-';
  193.                 l = -l;
  194.             }
  195.             p = ltoa(p, (unsigned long)l, 10);
  196.             break;
  197.         }
  198. #endif
  199.         if ((i = GETARG(int)) < 0) {
  200.             *p++ = '-';
  201.             i = -i;
  202.         }
  203.         p = _itoa(p, (unsigned int)i, 10);
  204.         break;
  205. #ifdef NO_FLOAT
  206.         case 'e':
  207.         case 'f':
  208.         case 'g':
  209.         zfill = ' ';
  210.         *p++ = '?';
  211.         break;
  212. #else
  213.         case 'e':
  214.         if (ndfnd == 0) ndigit = 6;
  215.         ndigit++;
  216.         p = _ecvt(p, GETARG(double), ndigit);
  217.         break;
  218.         case 'f':
  219.         if (ndfnd == 0) ndigit = 6;
  220.         p = _fcvt(p, GETARG(double), ndigit);
  221.         break;
  222.         case 'g':
  223.         if (ndfnd == 0) ndigit = 6;
  224.         p = _gcvt(p, GETARG(double), ndigit);
  225.         break;
  226. #endif
  227.         case 'c':
  228.         zfill = ' ';
  229.         *p++ = GETARG(int);
  230.         break;
  231.         case 's':
  232.         zfill = ' ';
  233.         if ((s = GETARG(char *)) == 0) s = "(null)";
  234.         if (ndigit == 0) ndigit = 32767;
  235.         for (p = s; *p && --ndigit >= 0; p++);
  236.         break;
  237.         default:    *p++ = c;              break;
  238.     }
  239.     i = p - s;
  240.     if ((width -= i) < 0) width = 0;
  241.     if (ljust == 0) width = -width;
  242.     if (width < 0) {
  243.         if (*s == '-' && zfill == '0') {
  244.             putc(*s++);
  245.             i--;
  246.         }
  247.         do
  248.             putc(zfill);
  249.         while (++width != 0);
  250.     }
  251.     while (--i >= 0) putc(*s++);
  252.     while (width) {
  253.         putc(zfill);
  254.         width--;
  255.     }
  256.   }
  257. }
  258.